如何实现给分类“添加成员变量”?

默认情况下,因为分类底层结构的限制,不能添加成员变量到分类中。但可以通过关联对象来间接实现

  • 关联对象提供了以下API
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // 添加关联对象
    void objc_setAssociatedObject(id object, const void * key,
    id value, objc_AssociationPolicy policy)

    // 获得关联对象
    id objc_getAssociatedObject(id object, const void * key)

    // 移除所有的关联对象
    void objc_removeAssociatedObjects(id object)

const void * key的常见用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
static void *MyKey = &MyKey;
objc_setAssociatedObject(obj, MyKey, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC)
objc_getAssociatedObject(obj, MyKey)

static char MyKey;
objc_setAssociatedObject(obj, &MyKey, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC)
objc_getAssociatedObject(obj, &MyKey)

// 使用属性名作为key
objc_setAssociatedObject(obj, @"property", value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_getAssociatedObject(obj, @"property");

// 使用get方法的@selecor作为key
objc_setAssociatedObject(obj, @selector(getter), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC)
objc_getAssociatedObject(obj, @selector(getter))

  • objc_AssociationPolicy:

  • 关联对象的原理:

    • 实现关联对象技术的核心对象有
      AssociationsManager
      AssociationsHashMap
      ObjectAssociationMap
      ObjcAssociation

void objc_setAssociatedObject(id object, const void * key, id value, objc_AssociationPolicy policy)

  • 关联对象并不是存储在被关联对象本身内存中
  • 关联对象存储在全局的统一的一个AssociationsManager中
  • 设置关联对象为nil,就相当于是移除关联对象

Share